/*
 * @lc app=leetcode.cn id=224 lang=cpp
 *
 * [224] 基本计算器
 */
#include "include.h"
// @lc code=start
class Solution {
public:
    int calculate(string s) {
        // todo :
        // 在放入之前先把栈内可以算的都算掉
        // 使用现有的 nums 和 ops 进行计算
        // 直到没有操作或者遇到左括号

        int n = s.size();

        std::stack<int> numberStack;
        std::stack<int> operationStack;

        int pointer = 0;

        while (pointer != n){
            switch (s[pointer])
            {
            case ' ':
                // do nothing
                {
                    pointer += 1;
                }
                break;
            case '+':
                {
                    operationStack.push(plus);
                    pointer += 1;
                }
                break;
            case '-':
                {
                    operationStack.push(minus);
                    pointer += 1;
                    break;
                }
            case '(':
                {
                    // if start with a '(', signal is '+'
                    if (operationStack.empty()){
                        operationStack.push(plus);
                    }

                    operationStack.push(left);
                    pointer += 1;
                    break;
                }
            case ')':
                {
                    int tokenSum = 0;
                    int topNum;
                    int topSignal = operationStack.top();

                    while (topSignal != left){
                        topNum = numberStack.top();
                        numberStack.pop();

                        operationStack.pop();
                        
                        if (topSignal == minus){tokenSum -= topNum;}
                        else {tokenSum += topNum;}

                        topSignal = operationStack.top();
                    }

                    // remove correspounding '(' signal
                    operationStack.pop();

                    // // even the token is minus 0, plus it
                    // operationStack.push(plus);
                    // no, we have pushed the signal of current '()' before

                    numberStack.push(tokenSum);
                    pointer += 1;
                    break;
                }
            default:
                {
                    // if start with a num, signal is '+'
                    if (operationStack.empty())
                    {
                        operationStack.push(plus);
                    }
                    // if inside () and start with a num, signal is '+'
                    else if (operationStack.top()== left)
                    {
                        operationStack.push(plus);
                    }
                    
                    // for num larger than 10 ~
                    int startIndex = pointer;

                    while (isNum(s[pointer])){
                        pointer += 1;
                        if (pointer == n){break;}
                    }

                    long int multiply = 1;
                    int num = 0;

                    for (int i=pointer - 1;i>=startIndex;i--){
                        int currentBit = s[i] - '0';
                        num += currentBit * multiply;
                        multiply *= 10;
                    }

                    numberStack.push(num);
                    // pointer += 1;
                }
                break;
            }
        }

        // now there is no '()' signal in the stack
        int res = 0;
        int topNum;
        int topSignal;
        while (!numberStack.empty()){
            topNum = numberStack.top();
            numberStack.pop();
            topSignal = operationStack.top();
            operationStack.pop();
            if (topSignal == minus){res -= topNum;}
            else {res += topNum;}
        }

        return res;
    }
private:
    enum signal{
        plus = 1,
        minus = -1,
        left = 0
    };
private:
    inline bool isNum(char& current){
        return current != ' ' and
               current != '+' and
               current != '-' and
               current != '(' and
               current != ')';
    }
};
// @lc code=end

int main(){
    // string test = "1 + 1";
    // string test = " 2-1 + 2 ";
    // string test = "(1+(4+5+2)-3)+(6+8)";
    string test = "2147483647";
    // string test = "(2)-(5-6)";
    Solution cal;
    int res = cal.calculate(test);
    printf("%d \n", res);
}